/**
  *@authors	Cameron Stewart, Tyler Williams, Fatimah Alowa, 
  *		Marlon Boothe,    Lauren Walker
  *@version	Group 2 Project 3 part 2
  *@since	2012-10-23
  */

#include <iostream>
#include <iomanip>
#include <time.h>
#include "Print.h"

const string symbolStrings[] =
{
    "<no token>", "<IDENTIFIER>", "<NUMBER>", "<STRING>",
    "^","*","(",")","-","+","=","[","]",":",";",
    "<",">",",",".","/",":=","<=",">=","<>","..",
    "<END OF FILE>", "<ERROR>",
    "AND","ARRAY","BEGIN","CASE","CONST","DIV","DO","DOWNTO",
    "ELSE","END","FILE","FOR","FUNCTION","GOTO","IF","IN",
    "LABEL","MOD","NIL","NOT","OF","OR","PACKED","PROCEDURE",
    "PROGRAM","RECORD","REPEAT","SET","THEN","TO","TYPE","UNTIL",
    "VAR","WHILE","WITH",
};

/** Constructor- sets the name of the file, the date and time,
	  *and initializes the lineCount to MAX_LINES_PER_PAGE so 
	  *a new page header is printed before anything else
	  */
Print::Print(const string &str){
    fName=str;
    time_t t;
	time(&t);
    date=asctime(localtime(&t));
    lineCount = MAX_LINES_PER_PAGE;
	
}

/**
	  *Destuctor
	  */
Print::~Print(){
    
}

*Ths method prints out the next line.  Checks to make sure the
  *lines for one page isnt greater than the max, else it will call PrintPageHeader method.
  *
  *@param &str      reference to the string to be printed
  *
  *@return void
  */
void Print::PrintLine(const string &str){
    char save_char = '\0';
	char *save_char_ptr = NULL;
    
	lineCount++;	
	if(lineCount >= MAX_LINES_PER_PAGE){
		PrintPageHeader();
	}
    

	if(sizeof(str)/sizeof(char *) > MAX_PRINT_LINE_LENGTH){
		save_char_ptr = (char*)&str[str.length()-1];
	}
	if(save_char_ptr != NULL){
		save_char = *save_char_ptr;
		save_char_ptr = '\0';
	}
	cout << str;
	if(save_char_ptr != NULL){
		save_char_ptr = &save_char;
	}

}

/**
	  *Increments the line count and prints the page header if the 
	  *lineCount is greater than the # allowed on one page
	  *Then the tokens are printed according to their type
	  *
	  *@param &tok	address of Tokenizer object.  used to retrieve tokens to 		  *		print
	  *@return 
	  */
void Print::PrintToken(Tokenizer &tok){
	lineCount++;
    if(lineCount >= MAX_LINES_PER_PAGE){
		PrintPageHeader();
	}
    
    if(tok.GetTokenCode()==STRING){
        cout << "  >> " << left << setw(MAX_RESERVED_WORD_LENGTH+TAB_SIZE) << symbolStrings[tok.GetTokenCode()] << tok.GetLiteral()->GetStringValue() << endl;
    }else if(tok.GetTokenCode()==NUMBER){
        if(tok.GetLiteral()->GetType()==REAL_LIT){
            cout << "  >> " << left << setw(MAX_RESERVED_WORD_LENGTH+TAB_SIZE) << symbolStrings[tok.GetTokenCode()] << tok.GetLiteral()->GetFloatValue() << endl;
        }else{
            cout << "  >> " << left << setw(MAX_RESERVED_WORD_LENGTH+TAB_SIZE) << symbolStrings[tok.GetTokenCode()] << tok.GetLiteral()->GetIntValue() << endl;
        }
    }else if(tok.GetTokenCode()==IDENTIFIER){
        cout << "  >> " << left << setw(MAX_RESERVED_WORD_LENGTH+TAB_SIZE) << symbolStrings[tok.GetTokenCode()] << tok.GetTokenString() << endl;
    }else{
        cout << "  >> " << left << setw(MAX_RESERVED_WORD_LENGTH+TAB_SIZE) << symbolStrings[tok.GetTokenCode()] << tok.GetTokenString() << endl;
    }
    
}

/** 
	  *Prints the page header whenever the max amount of lines
	  *for one page has been surpassed.  Consists of page# name and date
	  *
	  *@return void
	  */
void Print::PrintPageHeader(){
    static int page_number = 0;
    cout << FORM_FEED_CHAR;
    page_number++;
    cout << "Page\t" << page_number << "   " << fName << " " << date << endl;
    lineCount=0;
}